package com.yinshan.dialog.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.content.ContextCompat;
import android.text.InputFilter;
import android.util.AttributeSet;

import com.yinshan.dialog.R;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @author limh
 * @function
 * @date 2019/1/28 14:40
 */
public class SeparatedEditText extends android.support.v7.widget.AppCompatEditText {
    private static final int TYPE_HOLLOW = 1;
    private static final int TYPE_SOLID = 2;
    private static final int TYPE_UNDERLINE = 3;
    private Paint borderPaint;
    private Paint blockPaint;
    private Paint textPaint;
    private Paint cursorPaint;
    private RectF borderRectF;
    private RectF boxRectF;
    private int width;
    private int height;
    private int boxWidth;
    private int boxHeight;
    private int spacing;
    private int corner;
    private int maxLength;
    private int borderWidth;
    private boolean password;
    private boolean showCursor;
    private int cursorDuration;
    private int cursorWidth;
    private int cursorColor;
    private int type;
    private int borderColor;
    private int blockColor;
    private int textColor;
    private boolean isCursorShowing;
    private CharSequence contentText;
    private SeparatedEditText.TextChangedListener textChangedListener;
    private Timer timer;
    private TimerTask timerTask;

    public SeparatedEditText(Context context) {
        this(context, (AttributeSet)null);
    }

    public SeparatedEditText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SeparatedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SeparatedEditText);
        this.password = ta.getBoolean(R.styleable.SeparatedEditText_password, false);
        this.showCursor = ta.getBoolean(R.styleable.SeparatedEditText_showCursor, true);
        this.borderColor = ta.getColor(R.styleable.SeparatedEditText_borderColor, ContextCompat.getColor(this.getContext(), R.color.colorLine));
        this.blockColor = ta.getColor(R.styleable.SeparatedEditText_blockColor, ContextCompat.getColor(this.getContext(), R.color.colorLine));
        this.textColor = ta.getColor(R.styleable.SeparatedEditText_textColor, ContextCompat.getColor(this.getContext(), R.color.colorLine));
        this.cursorColor = ta.getColor(R.styleable.SeparatedEditText_cursorColor, ContextCompat.getColor(this.getContext(), R.color.colorLine));
        this.corner = (int)ta.getDimension(R.styleable.SeparatedEditText_corner, 0.0F);
        this.spacing = (int)ta.getDimension(R.styleable.SeparatedEditText_blockSpacing, 0.0F);
        this.type = ta.getInt(R.styleable.SeparatedEditText_separateType, 1);
        this.maxLength = ta.getInt(R.styleable.SeparatedEditText_maxLength, 6);
        this.cursorDuration = ta.getInt(R.styleable.SeparatedEditText_cursorDuration, 500);
        this.cursorWidth = (int)ta.getDimension(R.styleable.SeparatedEditText_cursorWidth, 2.0F);
        this.borderWidth = (int)ta.getDimension(R.styleable.SeparatedEditText_borderWidth, 5.0F);
        ta.recycle();
        this.init();
    }

    public void setSpacing(int spacing) {
        this.spacing = spacing;
        this.postInvalidate();
    }

    public void setCorner(int corner) {
        this.corner = corner;
        this.postInvalidate();
    }

    public void setMaxLength(int maxLength) {
        this.maxLength = maxLength;
        this.postInvalidate();
    }

    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        this.postInvalidate();
    }

    public void setPassword(boolean password) {
        this.password = password;
        this.postInvalidate();
    }

    public void setShowCursor(boolean showCursor) {
        this.showCursor = showCursor;
        this.postInvalidate();
    }

    public void setCursorDuration(int cursorDuration) {
        this.cursorDuration = cursorDuration;
        this.postInvalidate();
    }

    public void setCursorWidth(int cursorWidth) {
        this.cursorWidth = cursorWidth;
        this.postInvalidate();
    }

    public void setCursorColor(int cursorColor) {
        this.cursorColor = cursorColor;
        this.postInvalidate();
    }

    public void setType(int type) {
        this.type = type;
        this.postInvalidate();
    }

    public void setBorderColor(int borderColor) {
        this.borderColor = borderColor;
        this.postInvalidate();
    }

    public void setBlockColor(int blockColor) {
        this.blockColor = blockColor;
        this.postInvalidate();
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
        this.postInvalidate();
    }

    private void init() {
        this.setFocusableInTouchMode(true);
        this.setFocusable(true);
        this.requestFocus();
        this.setCursorVisible(false);
        this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(this.maxLength)});
        this.blockPaint = new Paint();
        this.blockPaint.setAntiAlias(true);
        this.blockPaint.setColor(this.blockColor);
        this.blockPaint.setStyle(Paint.Style.FILL);
        this.blockPaint.setStrokeWidth(1.0F);
        this.textPaint = new Paint();
        this.textPaint.setAntiAlias(true);
        this.textPaint.setColor(this.textColor);
        this.textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        this.textPaint.setStrokeWidth(1.0F);
        this.borderPaint = new Paint();
        this.borderPaint.setAntiAlias(true);
        this.borderPaint.setColor(this.borderColor);
        this.borderPaint.setStyle(Paint.Style.STROKE);
        this.borderPaint.setStrokeWidth((float)this.borderWidth);
        this.cursorPaint = new Paint();
        this.cursorPaint.setAntiAlias(true);
        this.cursorPaint.setColor(this.cursorColor);
        this.cursorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        this.cursorPaint.setStrokeWidth((float)this.cursorWidth);
        this.borderRectF = new RectF();
        this.boxRectF = new RectF();
        if (this.type == 1) {
            this.spacing = 0;
        }

        this.timerTask = new TimerTask() {
            public void run() {
                SeparatedEditText.this.isCursorShowing = !SeparatedEditText.this.isCursorShowing;
                SeparatedEditText.this.postInvalidate();
            }
        };
        this.timer = new Timer();
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.width = w;
        this.height = h;
        this.boxWidth = (this.width - this.spacing * (this.maxLength + 1)) / this.maxLength;
        this.boxHeight = this.height;
        this.borderRectF.set(0.0F, 0.0F, (float)this.width, (float)this.height);
        this.textPaint.setTextSize((float)(this.boxWidth / 2));
    }

    protected void onDraw(Canvas canvas) {
        this.drawRect(canvas);
        this.drawText(canvas, this.contentText);
        this.drawCursor(canvas);
    }

    private void drawCursor(Canvas canvas) {
        if (!this.isCursorShowing && this.showCursor && this.contentText.length() < this.maxLength && this.hasFocus()) {
            int cursorPosition = this.contentText.length() + 1;
            int startX = this.spacing * cursorPosition + this.boxWidth * (cursorPosition - 1) + this.boxWidth / 2;
            int startY = this.boxHeight / 4;
            int endY = this.boxHeight - this.boxHeight / 4;
            canvas.drawLine((float)startX, (float)startY, (float)startX, (float)endY, this.cursorPaint);
        }

    }

    private void drawRect(Canvas canvas) {
        for(int i = 0; i < this.maxLength; ++i) {
            this.boxRectF.set((float)(this.spacing * (i + 1) + this.boxWidth * i), 0.0F, (float)(this.spacing * (i + 1) + this.boxWidth * i + this.boxWidth), (float)this.boxHeight);
            if (this.type == 2) {
                canvas.drawRoundRect(this.boxRectF, (float)this.corner, (float)this.corner, this.blockPaint);
            } else if (this.type == 3) {
                canvas.drawLine(this.boxRectF.left, this.boxRectF.bottom, this.boxRectF.right, this.boxRectF.bottom, this.borderPaint);
            } else if (this.type == 1 && i != 0 && i != this.maxLength) {
                canvas.drawLine(this.boxRectF.left, this.boxRectF.top, this.boxRectF.left, this.boxRectF.bottom, this.borderPaint);
            }
        }

        if (this.type == 1) {
            canvas.drawRoundRect(this.borderRectF, (float)this.corner, (float)this.corner, this.borderPaint);
        }

    }

    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        this.contentText = text;
        this.invalidate();
        if (this.textChangedListener != null) {
            if (text.length() == this.maxLength) {
                this.textChangedListener.textCompleted(text);
            } else {
                this.textChangedListener.textChanged(text);
            }
        }

    }

    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        this.timer.scheduleAtFixedRate(this.timerTask, 0L, (long)this.cursorDuration);
    }

    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        this.timer.cancel();
    }

    private void drawText(Canvas canvas, CharSequence charSequence) {
        for(int i = 0; i < charSequence.length(); ++i) {
            int startX = this.spacing * (i + 1) + this.boxWidth * i;
            int startY = 0;
            int baseX = (int)((float)(startX + this.boxWidth / 2) - this.textPaint.measureText(String.valueOf(charSequence.charAt(i))) / 2.0F);
            int baseY = (int)((float)(startY + this.boxHeight / 2) - (this.textPaint.descent() + this.textPaint.ascent()) / 2.0F);
            int centerX = startX + this.boxWidth / 2;
            int centerY = startY + this.boxHeight / 2;
            int radius = Math.min(this.boxWidth, this.boxHeight) / 6;
            if (this.password) {
                canvas.drawCircle((float)centerX, (float)centerY, (float)radius, this.textPaint);
            } else {
                canvas.drawText(String.valueOf(charSequence.charAt(i)), (float)baseX, (float)baseY, this.textPaint);
            }
        }

    }

    public void setTextChangedListener(SeparatedEditText.TextChangedListener listener) {
        this.textChangedListener = listener;
    }

    public void clearText() {
        this.setText("");
    }

    public interface TextChangedListener {
        void textChanged(CharSequence var1);

        void textCompleted(CharSequence var1);
    }
}
